package com.sangmo.fts.process.factoring.service;

import com.sangmo.boot.framework.common.errors.ServiceException;
import com.sangmo.boot.framework.common.errors.StandardErrors;
import com.sangmo.boot.framework.data.filter.PageResult;
import com.sangmo.boot.framework.data.filter.PageSearch;
import com.sangmo.boot.framework.data.filter.ValueFilter;
import com.sangmo.boot.framework.plugin.dataview.crud.service.DelegateViewService;
import com.sangmo.boot.framework.plugin.dataview.crud.service.ViewService;
import com.sangmo.fts.basic.model.Goods;
import com.sangmo.fts.basic.service.GoodsService;
import com.sangmo.fts.process.factoring.model.FfContract;
import com.sangmo.fts.process.factoring.model.FfContractItem;
import com.sangmo.fts.process.storage.model.CsfContract;
import com.sangmo.fts.process.storage.model.CsfContractItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class FfContractService extends DelegateViewService<FfContract> {

    @Autowired
    private FfContractEntityService ffContractEntityService;

    @Autowired
    private FfContractItemEntityService ffContractItemEntityService;

    @Autowired
    private GoodsService goodsService;

    @Override
    protected ViewService<FfContract> getEntityService() {
        return ffContractEntityService;
    }

    public void buyerConfirm(Long id) {
        FfContract contract = this.get(id);
        if (null == contract.getBuyerConfirmDoc()) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.rpfContract.buyerConfirm.permit.disabled");
        }
        if (contract.isBuyerConfirm()) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.rpfContract.buyerConfirm.state.wrong");
        }
        ffContractEntityService.buyerConfirm(contract);
    }

    public void sellerConfirm(Long id) {
        FfContract contract = this.get(id);
        if (null == contract.getSellerConfirmDoc()) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.rpfContract.sellerConfirm.permit.disabled");
        }
        if (contract.isSellerConfirm()) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.rpfContract.sellerConfirm.state.wrong");
        }
        ffContractEntityService.sellerConfirm(contract);
    }

    public List<FfContractItem> listItemsByContractId(Long contractId) {
        return ffContractItemEntityService.findByContractId(contractId);
    }

    public BigDecimal calculateContractAmount(Long id) {
        FfContract contract = this.get(id);
        List<FfContractItem> contractItems = ffContractItemEntityService.findByContractId(contract.getId());
        BigDecimal contractAmount = BigDecimal.ZERO;
        Map<Long, Goods> goodsMap = goodsService.getAllGoodsMapCache();
        for (FfContractItem item : contractItems) {
            Goods goods = goodsMap.get(item.getGoodsId());
            if (null == goods) {
                throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.ffContract.goods.amount.wrong");
            }
            contractAmount = contractAmount.add(goods.getPrice().multiply(item.getQuantity()));
        }
        return contractAmount;
    }

    public PageResult<FfContract> selection(PageSearch ps) {
        ps.getFilters().add(new ValueFilter("buyerConfirm", ValueFilter.OP_EQ, true));
        ps.getFilters().add(new ValueFilter("sellerConfirm", ValueFilter.OP_EQ, true));
        return super.search(ps);
    }
}
